Micron Document
🎖️GitЯра🎖️

Node / meshtastic / Meshtastic-Android / files / scripts / validate-doc-links.js

Displaying Raw • Download

scripts/validate-doc-links.js renovate/net.java.dev.jna-jna-5.x (5a8f4966) Text, 2.91 KB

T8b949e#!/usr/bin/env node
T8b949e// scripts/validate-doc-links.js
T8b949e// Validates internal cross-references and image paths in in-app documentation.
T8b949e// Exit 0 = all valid, Exit 1 = broken links found.
T8b949e//
T8b949e// Usage: node scripts/validate-doc-links.js [docs-dir]

Ta5d6ff"use strict"Tb4b4b4;

Tff7b72const Te6edf3fs Tff7b72= Te6edf3requireTb4b4b4(Ta5d6ff"fs"Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3path Tff7b72= Te6edf3requireTb4b4b4(Ta5d6ff"path"Tb4b4b4)Tb4b4b4;
Tff7b72const Tb4b4b4{ Te6edf3discoverSlugsTb4b4b4, Te6edf3forEachDocPage Tb4b4b4} Tff7b72= Te6edf3requireTb4b4b4(Ta5d6ff"./lib/frontmatter"Tb4b4b4)Tb4b4b4;

Tff7b72const Te6edf3DOCS_DIR Tff7b72= Te6edf3pathTb4b4b4.Te6edf3resolveTb4b4b4(Te6edf3processTb4b4b4.Te6edf3argvTb4b4b4[T79c0ff2Tb4b4b4] Tff7b72|| Te6edf3pathTb4b4b4.Te6edf3joinTb4b4b4(Ta5d6ff"docs"Tb4b4b4, Ta5d6ff"en"Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// Assets (screenshots) live at docs/ root, not inside the en/ locale folder
Tff7b72const Te6edf3DOCS_ROOT Tff7b72= Te6edf3pathTb4b4b4.Te6edf3resolveTb4b4b4(Te6edf3DOCS_DIRTb4b4b4, Ta5d6ff".."Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3IMAGE_EXTS Tff7b72= Tff7b72new Tffa657SetTb4b4b4(Tb4b4b4[Ta5d6ff".png"Tb4b4b4, Ta5d6ff".jpg"Tb4b4b4, Ta5d6ff".jpeg"Tb4b4b4, Ta5d6ff".gif"Tb4b4b4, Ta5d6ff".svg"Tb4b4b4, Ta5d6ff".webp"Tb4b4b4]Tb4b4b4)Tb4b4b4;

T8b949e// Collect known page slugs from both sections
Tff7b72const Te6edf3knownPages Tff7b72= Tff7b72new Tffa657SetTb4b4b4(Tb4b4b4[
Tb4b4b4...Te6edf3discoverSlugsTb4b4b4(Te6edf3DOCS_DIRTb4b4b4, Ta5d6ff"user"Tb4b4b4)Tb4b4b4,
Tb4b4b4...Te6edf3discoverSlugsTb4b4b4(Te6edf3DOCS_DIRTb4b4b4, Ta5d6ff"developer"Tb4b4b4)Tb4b4b4,
Tb4b4b4]Tb4b4b4)Tb4b4b4;

Te6edf3consoleTb4b4b4.Te6edf3logTb4b4b4(Ta5d6ff`Ta5d6ffValidating links across Tffd700${Te6edf3knownPagesTb4b4b4.Te6edf3sizeTffd700}Ta5d6ff doc pages in Tffd700${Te6edf3DOCS_DIRTffd700}Ta5d6ff...Ta5d6ff`Tb4b4b4)Tb4b4b4;

Tff7b72let Te6edf3errors Tff7b72= T79c0ff0Tb4b4b4;

Te6edf3forEachDocPageTb4b4b4(Te6edf3DOCS_DIRTb4b4b4, Tb4b4b4(Te6edf3filePathTb4b4b4, Te6edf3slugTb4b4b4, Te6edf3sectionTb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3lines Tff7b72= Te6edf3fsTb4b4b4.Te6edf3readFileSyncTb4b4b4(Te6edf3filePathTb4b4b4, Ta5d6ff"utf-8"Tb4b4b4)Tb4b4b4.Te6edf3splitTb4b4b4(Ta5d6ff"\n"Tb4b4b4)Tb4b4b4;

Te6edf3linesTb4b4b4.Te6edf3forEachTb4b4b4(Tb4b4b4(Te6edf3lineTb4b4b4, Te6edf3idxTb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3lineNum Tff7b72= Te6edf3idx Tff7b72+ T79c0ff1Tb4b4b4;

T8b949e// Check markdown links (non-image)
Tff7b72let Te6edf3matchTb4b4b4;
Tff7b72const Te6edf3linkRe Tff7b72= Ta5d6ff/(?<!!)\[([^\]]*)\]\(([^)]+)\)/gTb4b4b4;
Tff7b72while Tb4b4b4(Tb4b4b4(Te6edf3match Tff7b72= Te6edf3linkReTb4b4b4.Te6edf3execTb4b4b4(Te6edf3lineTb4b4b4)Tb4b4b4) Tff7b72!== Tff7b72nullTb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3target Tff7b72= Te6edf3matchTb4b4b4[T79c0ff2Tb4b4b4]Tb4b4b4;

Tff7b72if Tb4b4b4(Ta5d6ff/^(https?:|mailto:|#)/Tb4b4b4.Te6edf3testTb4b4b4(Te6edf3targetTb4b4b4)Tb4b4b4) Tff7b72continueTb4b4b4;

Tff7b72const Te6edf3ext Tff7b72= Te6edf3pathTb4b4b4.Te6edf3extnameTb4b4b4(Te6edf3targetTb4b4b4)Tb4b4b4.Te6edf3toLowerCaseTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3IMAGE_EXTSTb4b4b4.Te6edf3hasTb4b4b4(Te6edf3extTb4b4b4)Tb4b4b4) Tff7b72continueTb4b4b4;

Tff7b72let Te6edf3targetSlug Tff7b72= Te6edf3target
Tb4b4b4.Te6edf3replaceTb4b4b4(Ta5d6ff/\.md$/Tb4b4b4, Ta5d6ff""Tb4b4b4)
Tb4b4b4.Te6edf3replaceTb4b4b4(Ta5d6ff/^\.\//Tb4b4b4, Ta5d6ff""Tb4b4b4)
Tb4b4b4.Te6edf3replaceTb4b4b4(Ta5d6ff/#.*$/Tb4b4b4, Ta5d6ff""Tb4b4b4)Tb4b4b4;

Tff7b72const Te6edf3crossMatch Tff7b72= Te6edf3targetSlugTb4b4b4.Te6edf3matchTb4b4b4(Ta5d6ff/^\.\.\/\w+\/(.+)/Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3crossMatchTb4b4b4) Te6edf3targetSlug Tff7b72= Te6edf3crossMatchTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4;
Te6edf3targetSlug Tff7b72= Te6edf3targetSlugTb4b4b4.Te6edf3splitTb4b4b4(Ta5d6ff"/"Tb4b4b4)Tb4b4b4.Te6edf3popTb4b4b4(Tb4b4b4)Tb4b4b4;

Tff7b72if Tb4b4b4(Te6edf3targetSlug Tff7b72&& Tff7b72!Te6edf3knownPagesTb4b4b4.Te6edf3hasTb4b4b4(Te6edf3targetSlugTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3consoleTb4b4b4.Te6edf3logTb4b4b4(Ta5d6ff`Ta5d6ff ERROR: Tffd700${Te6edf3sectionTffd700}Ta5d6ff/Tffd700${Te6edf3slugTffd700}Ta5d6ff.md:Tffd700${Te6edf3lineNumTffd700}Ta5d6ff — broken link to 'Tffd700${Te6edf3targetSlugTffd700}Ta5d6ff'Ta5d6ff`Tb4b4b4)Tb4b4b4;
Te6edf3errorsTff7b72++Tb4b4b4;
Tb4b4b4}
Tb4b4b4}

T8b949e// Check image references
Tff7b72let Te6edf3imgMatchTb4b4b4;
Tff7b72const Te6edf3imgRe Tff7b72= Ta5d6ff/!\[([^\]]*)\]\(([^)]+)\)/gTb4b4b4;
Tff7b72while Tb4b4b4(Tb4b4b4(Te6edf3imgMatch Tff7b72= Te6edf3imgReTb4b4b4.Te6edf3execTb4b4b4(Te6edf3lineTb4b4b4)Tb4b4b4) Tff7b72!== Tff7b72nullTb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3imgPath Tff7b72= Te6edf3imgMatchTb4b4b4[T79c0ff2Tb4b4b4]Tb4b4b4;
Tff7b72if Tb4b4b4(Ta5d6ff/^https?:/Tb4b4b4.Te6edf3testTb4b4b4(Te6edf3imgPathTb4b4b4)Tb4b4b4) Tff7b72continueTb4b4b4;

Tff7b72const Te6edf3resolved Tff7b72= Te6edf3imgPathTb4b4b4.Te6edf3startsWithTb4b4b4(Ta5d6ff"/"Tb4b4b4)
Tff7b72? Te6edf3pathTb4b4b4.Te6edf3joinTb4b4b4(Te6edf3DOCS_ROOTTb4b4b4, Te6edf3imgPathTb4b4b4)
Tff7b72: Te6edf3pathTb4b4b4.Te6edf3resolveTb4b4b4(Te6edf3pathTb4b4b4.Te6edf3dirnameTb4b4b4(Te6edf3filePathTb4b4b4)Tb4b4b4, Te6edf3imgPathTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3fsTb4b4b4.Te6edf3existsSyncTb4b4b4(Te6edf3resolvedTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3consoleTb4b4b4.Te6edf3logTb4b4b4(Ta5d6ff`Ta5d6ff ERROR: Tffd700${Te6edf3sectionTffd700}Ta5d6ff/Tffd700${Te6edf3slugTffd700}Ta5d6ff.md:Tffd700${Te6edf3lineNumTffd700}Ta5d6ff — missing image 'Tffd700${Te6edf3imgPathTffd700}Ta5d6ff'Ta5d6ff`Tb4b4b4)Tb4b4b4;
Te6edf3errorsTff7b72++Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Tff7b72if Tb4b4b4(Te6edf3errors Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3consoleTb4b4b4.Te6edf3logTb4b4b4(Ta5d6ff`Ta5d6ff\nTa5d6ffFAILED: Tffd700${Te6edf3errorsTffd700}Ta5d6ff broken link(s) found.Ta5d6ff`Tb4b4b4)Tb4b4b4;
Te6edf3processTb4b4b4.Te6edf3exitTb4b4b4(T79c0ff1Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3consoleTb4b4b4.Te6edf3logTb4b4b4(Ta5d6ff"PASSED: All internal links and images are valid."Tb4b4b4)Tb4b4b4;
Te6edf3processTb4b4b4.Te6edf3exitTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4;
Tb4b4b4}

Served by rngit 1.4.2 - Generated in 0.07s